package com.arpa.wms.service.impl;

import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.arpa.core.web.Result;
import com.arpa.ntocc.common.common.Page;
import com.arpa.ntocc.common.common.cache.DictCache;
import com.arpa.ntocc.common.common.cache.DictCacheDO;
import com.arpa.ntocc.common.common.cache.PartyCache;
import com.arpa.ntocc.common.common.cache.ShipmentCache;
import com.arpa.ntocc.common.common.exception.ServiceException;
import com.arpa.ntocc.common.common.util.CommonUtil;
import com.arpa.ntocc.common.common.util.UserUtil;
import com.arpa.ntocc.common.domain.entity.Dict;
import com.arpa.ntocc.common.service.IDictService;
import com.arpa.oms.domain.entity.OmsReceivable;
import com.arpa.wms.cache.BrandCache;
import com.arpa.wms.common.ess.ESSElectronicFaceSheetBalanceVO;
import com.arpa.wms.common.ess.ESSElectronicFaceSheetVO;
import com.arpa.wms.common.ess.ElectronicFaceSheetBlanaceDTO;
import com.arpa.wms.common.util.ArpaCloudUtil;
import com.arpa.wms.common.util.UUIDUtil;
import com.arpa.wms.domain.consts.NumConst;
import com.arpa.wms.domain.consts.PropertyConst;
import com.arpa.wms.domain.consts.ResultDO;
import com.arpa.wms.domain.dto.BrandDTO;
import com.arpa.wms.domain.dto.FaceBillBalanceDTO;
import com.arpa.wms.domain.entity.*;
import com.arpa.wms.domain.enums.DeleteFlagEnum;
import com.arpa.wms.domain.enums.StatusEnum;
import com.arpa.wms.domain.vo.BrandVO;
import com.arpa.wms.domain.vo.FaceBillBalanceVO;
import com.arpa.wms.domain.vo.GoodsVO;
import com.arpa.wms.mapper.BrandMapper;
import com.arpa.wms.mapper.FaceBillBalanceMapper;
import com.arpa.wms.mapper.GoodsMapper;
import com.arpa.wms.service.FaceBillBalanceService;
import com.arpa.wms.service.IBrandService;
import com.arpa.wms.service.ICarrierService;
import com.arpa.wms.service.IShopService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.qimen.api.request.ItemsSynchronizeRequest;
import com.qimen.api.request.SingleitemSynchronizeRequest;
import jdk.nashorn.internal.scripts.JD;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.arpa.wms.domain.consts.CommonConst.DAMAGED_TYPE;
import static com.arpa.wms.domain.consts.NumConst.NUM_ONE;

/**
 * <p>
 * 面单余额 服务实现类
 * </p>
 *
 * @author LEO
 * @since 2020-08-03
 */
@Service
@Log4j2
public class FaceBillBalanceServiceImpl extends ServiceImpl<FaceBillBalanceMapper, FaceBillBalance> implements FaceBillBalanceService {

    @Autowired
    private IShopService iShopService;

    @Autowired
    private ArpaCloudUtil arpaCloudUtil;

    @Autowired
    private PartyCache partyCache;

    @Autowired
    private ICarrierService iCarrierService;

    @Autowired
    private DictCache dictCache;

    @Override
    public int updateByCode(FaceBillBalanceDTO entity) {
        entity.setGroupCode(UserUtil.getBranchCode());
        Shop shop = iShopService.getOne(new QueryWrapper<Shop>().lambda()
                .eq(Shop::getCode, entity.getShopCode()).eq(Shop::getGroupCode, entity.getGroupCode())
                .eq(Shop::getStatus, "1"));
        if(ObjectUtil.isNull(shop)){
            throw new ServiceException("店铺不存在！");
        }
        if(StringUtils.isEmpty(shop.getAccessToken()) || StringUtils.isEmpty(shop.getAppKey()) || StringUtils.isEmpty(shop.getAppSecret())){
            throw new ServiceException("店铺维护基础数据不全,请查看！");
        }
        //不管新增还是修改先校验一下
        updateOrSave(entity,shop);

        FaceBillBalance faceBillBalance = new FaceBillBalance();
        BeanUtils.copyProperties(entity,faceBillBalance);
        faceBillBalance.setModifiedBy(UserUtil.getCode());
        faceBillBalance.setModifiedName(partyCache.translate(UserUtil.getCode()));
        faceBillBalance.setGmtModified(LocalDateTime.now());
        //查询账户余额正常 修改
        return baseMapper.update(faceBillBalance,new QueryWrapper<FaceBillBalance>().lambda()
                .eq(FaceBillBalance::getCode,entity.getCode()).eq(FaceBillBalance::getGroupCode,UserUtil.getBranchCode()));
    }

    @Override
    @Async
    public void getMethodResult(Delivery delivery) {
        try {
            Carrier carrier = iCarrierService.getOne(new QueryWrapper<Carrier>().lambda().eq(Carrier::getCode, delivery.getCarrierCode())
                    .eq(Carrier::getGroupCode, delivery.getGroupCode()));
            if(ObjectUtil.isNull(carrier)){
                log.info("取消电子面单：承运商不存在!");
            }
            Shop shopC = iShopService.getOne(new QueryWrapper<Shop>().lambda()
                    .like(Shop::getCode, carrier.getShopCode()).eq(Shop::getGroupCode, delivery.getGroupCode())
                    .eq(Shop::getStatus, "1"));
            if(ObjectUtil.isNull(shopC)){
                log.info("取消电子面单：店铺不存在！");
            }
            //这里的查询各个平台的店铺 名称是写死的  提前维护好这几个平台  唯一
            Shop shop = new Shop();
            int type = 0;
            switch (carrier.getPlatformType()){
                case "JD":{
                    type = 2;
                    break;
                }
                case "PDD": {
                    type = 3;
                    shop = iShopService.getOne(new QueryWrapper<Shop>().lambda()
                            .like(Shop::getName, "(拼多多面单)").eq(Shop::getGroupCode, delivery.getGroupCode())
                            .eq(Shop::getStatus, "1"));
                    break;
                }
                case "DY": {
                    type = 4;
                    shop = iShopService.getOne(new QueryWrapper<Shop>().lambda()
                            .like(Shop::getName, "(抖音面单)").eq(Shop::getGroupCode, delivery.getGroupCode())
                            .eq(Shop::getStatus, "1"));
                    break;
                }
                case "TB": {
                    type = 5;
                    shop = iShopService.getOne(new QueryWrapper<Shop>().lambda()
                            .like(Shop::getName, "(淘宝面单)").eq(Shop::getGroupCode, delivery.getGroupCode())
                            .eq(Shop::getStatus, "1"));
                    break;
                }
                case "CAINIAO": {
                    type = 1;
                    shop = iShopService.getOne(new QueryWrapper<Shop>().lambda()
                            .like(Shop::getName, "(菜鸟面单)").eq(Shop::getGroupCode, delivery.getGroupCode())
                            .eq(Shop::getStatus, "1"));
                    break;
                }
                case "KS": {
                    type = 6;
//                    shop = iShopService.getOne(new QueryWrapper<Shop>().lambda()
//                            .like(Shop::getName, "(快手面单)").eq(Shop::getGroupCode, delivery.getGroupCode())
//                            .eq(Shop::getStatus, "1"));
                    break;
                }
                default: {
                    type = 0;
                }
            }
            if(ObjectUtil.isNull(shop)){
                log.info("取消电子面单：店铺维护基础数据不全,请查看！" + carrier.toString());
            }
            if(StringUtils.isEmpty(shop.getAccessToken()) || StringUtils.isEmpty(shop.getAppKey()) || StringUtils.isEmpty(shop.getAppSecret())){
                log.info("取消电子面单：店铺维护基础数据不全,请查看！"  + shop.toString());
            }
            //暂时不支持京东的取消面单
            if(type != 2 && type != 0){
                //拼接
                ElectronicFaceSheetBlanaceDTO electronicFaceSheetBlanaceDTO = new ElectronicFaceSheetBlanaceDTO();
                electronicFaceSheetBlanaceDTO.setType(type);
                electronicFaceSheetBlanaceDTO.setDynamicToken(shop.getAccessToken());
                electronicFaceSheetBlanaceDTO.setAppKey(shop.getAppKey());
                electronicFaceSheetBlanaceDTO.setAppSecret(shop.getAppSecret());
                electronicFaceSheetBlanaceDTO.setCpCode(carrier.getOuterCode());
                String waybillCode = delivery.getWaybillCode();
                String splitWaybillCode = delivery.getSplitWaybillCode();
                List<String> list = new ArrayList<>();
                if(StringUtils.isNotEmpty(splitWaybillCode)){
                    String[] split = splitWaybillCode.split(",");
                    list = Arrays.asList(split);
                }
                list.add(waybillCode);
                for (String key:list){
                    if(StringUtils.isNotEmpty(key)){
                        electronicFaceSheetBlanaceDTO.setWaybillCode(key);
                        //先调用获取面单余额的接口 避免异常
                        ResultDO resultDO = arpaCloudUtil.cancelwaybillPrintData(electronicFaceSheetBlanaceDTO, carrier.getGroupCode());
                        if (resultDO.getStatus() != 0) {
                            JSONObject result = null;
                            String msg = StrUtil.EMPTY;
                            try {
                                result = JSONUtil.parseObj(resultDO.getData());
                                msg = (String) result.get("msg");
                            } catch (Exception e) {
                                log.error("取消电子面单异常：" + e);
                            }
                            log.error("{}:{}", "取消电子面单异常：", msg);
                        }
                    }
                }
            }
        }catch (Exception e){
            log.error("取消电子面单异常：" + e);
        }
    }

    @Override
    public void saveFaceBillBalance(FaceBillBalanceDTO faceBillBalanceDTO) {
        Shop shop = iShopService.getOne(new QueryWrapper<Shop>().lambda()
                .eq(Shop::getCode, faceBillBalanceDTO.getShopCode()).eq(Shop::getGroupCode, faceBillBalanceDTO.getGroupCode())
                .eq(Shop::getStatus, "1"));
        if(ObjectUtil.isNull(shop)){
            throw new ServiceException("店铺不存在！");
        }
        if(StringUtils.isEmpty(shop.getAccessToken()) || StringUtils.isEmpty(shop.getAppKey()) || StringUtils.isEmpty(shop.getAppSecret())){
            throw new ServiceException("店铺维护基础数据不全,请查看！");
        }

        //不管新增还是修改先校验一下
        updateOrSave(faceBillBalanceDTO,shop);

        FaceBillBalance faceBillBalance = new FaceBillBalance();
        BeanUtils.copyProperties(faceBillBalanceDTO,faceBillBalance);
        faceBillBalance.setCreatedBy(UserUtil.getCode());
        faceBillBalance.setCreatedName(partyCache.translate(UserUtil.getCode()));
        faceBillBalance.setGmtCreated(LocalDateTime.now());
        faceBillBalance.setModifiedBy(UserUtil.getCode());
        faceBillBalance.setModifiedName(partyCache.translate(UserUtil.getCode()));
        faceBillBalance.setGmtModified(LocalDateTime.now());
        if(StringUtils.isBlank(faceBillBalance.getCode())){
            faceBillBalance.setCode(IdUtil.simpleUUID());
        }
        //查询账户余额正常 保存
        this.save(faceBillBalance);
    }

    private void updateOrSave(FaceBillBalanceDTO faceBillBalanceDTO, Shop shop) {
        int type = 1;
        switch (faceBillBalanceDTO.getSourcePlatformCode()){
            case "JD":{
                type = 2;
                break;
            }
            case "PDD": {
                type = 3;
                break;
            }
            case "DY": {
                type = 4;
                break;
            }
            case "TB": {
                type = 5;
                break;
            }
            case "KS": {
                type = 6;
                break;
            }
            default: {
                type = 1;
            }
        }
        if(type == 2 && StringUtils.isEmpty(shop.getMerchantsCode())){
            throw new ServiceException("店铺维护基础数据不全,请查看,京东缺少商家编码！");
        }
        //拼接
        ElectronicFaceSheetBlanaceDTO electronicFaceSheetBlanaceDTO = new ElectronicFaceSheetBlanaceDTO();
        electronicFaceSheetBlanaceDTO.setType(type);
        electronicFaceSheetBlanaceDTO.setDynamicToken(shop.getAccessToken());
        electronicFaceSheetBlanaceDTO.setAppKey(shop.getAppKey());
        electronicFaceSheetBlanaceDTO.setAppSecret(shop.getAppSecret());
        electronicFaceSheetBlanaceDTO.setCpCode(faceBillBalanceDTO.getOuterCode());
        if(type == 2){
            electronicFaceSheetBlanaceDTO.setMallMerchantCode(shop.getMerchantsCode());
        }
        //先调用获取面单余额的接口 避免异常
        ResultDO resultDO = arpaCloudUtil.getWaybillPrintDataBalance(electronicFaceSheetBlanaceDTO, faceBillBalanceDTO.getGroupCode());
        log.info("从中台获取到的电子面单余额信息为,{}", JSONUtil.toJsonStr(resultDO));
        if (resultDO.getStatus() != 0) {
            JSONObject result = null;
            String msg = StrUtil.EMPTY;
            try {
                result = JSONUtil.parseObj(resultDO.getData());
                msg = (String) result.get("msg");
            } catch (Exception e) {
                //如果解析为JSONObject报异常，在尝试解析为List
                List<Map> resultMapList = JSONUtil.toList(JSONUtil.toJsonStr(resultDO.getData()), Map.class);
                if (IterUtil.isEmpty(resultMapList)){
                    throw new ServiceException("获取面单余额异常，异常信息为：" + JSONUtil.toJsonStr(resultDO.getData()));
                } else {
                    msg = (String)resultMapList.get(NumConst.NUM_ZERO).get("msg");
                }
            }
            log.error("{}:{}", "获取面单余额异常：", msg);
            throw new ServiceException("获取面单余额异常：" + msg);
        }
    }


    @Override
    public List<FaceBillBalanceVO> queryList(FaceBillBalanceDTO faceBillBalanceDTO) {
        List<FaceBillBalanceVO> faceBillBalanceVOS = baseMapper.queryList(faceBillBalanceDTO);

        List<DictCacheDO> JD = dictCache.getListByType("JD",UserUtil.getBranchCode());

        List<DictCacheDO> PDD = dictCache.getListByType("PDD",UserUtil.getBranchCode());

        List<DictCacheDO> DY = dictCache.getListByType("DY",UserUtil.getBranchCode());

        List<DictCacheDO> TB = dictCache.getListByType("TB",UserUtil.getBranchCode());

        List<DictCacheDO> KS = dictCache.getListByType("KS",UserUtil.getBranchCode());

        List<DictCacheDO> dictCacheAll = dictCache.getListByType("salePlatform",UserUtil.getBranchCode());
        for (int z = 0;z<faceBillBalanceVOS.size();z++){
            FaceBillBalanceVO faceBillBalanceVO = faceBillBalanceVOS.get(z);
            Shop shop = iShopService.getOne(new QueryWrapper<Shop>().lambda()
                    .eq(Shop::getCode, faceBillBalanceVO.getShopCode()).eq(Shop::getGroupCode, faceBillBalanceVO.getGroupCode())
                    .eq(Shop::getStatus, "1"));

            if(ObjectUtil.isNull(shop)){
                throw new ServiceException("店铺不存在！");
            }
            if(StringUtils.isEmpty(shop.getAccessToken()) || StringUtils.isEmpty(shop.getAppKey()) || StringUtils.isEmpty(shop.getAppSecret())){
                throw new ServiceException("店铺维护基础数据不全,请查看！");
            }
            if(faceBillBalanceVO.getSourcePlatformCode().equals("JD") && StringUtils.isEmpty(shop.getMerchantsCode())){
                throw new ServiceException("店铺维护基础数据不全,请查看,京东缺少商家编码！");
            }
            //查询面单余额并赋值
            faceBillBalanceData(faceBillBalanceVO,shop,JD,PDD,DY,TB,KS);

            List<DictCacheDO> dictCacheDOList = dictCacheAll.stream().filter(item -> item.getCode().equals(faceBillBalanceVO.getSourcePlatformCode())).collect(Collectors.toList());
            if(ObjectUtil.isNotNull(dictCacheDOList) && dictCacheDOList.size() > 0){
                faceBillBalanceVO.setSourcePlatformName(dictCacheDOList.get(0).getName());
            }
        }
        return faceBillBalanceVOS;
    }



    @Async
    public void faceBillBalanceData(FaceBillBalanceVO faceBillBalanceDTO,Shop shop,List<DictCacheDO> JD,List<DictCacheDO> PDD,List<DictCacheDO> DY,List<DictCacheDO> TB,List<DictCacheDO> KS) {
        int type = 1;
        switch (faceBillBalanceDTO.getSourcePlatformCode()){
            case "JD":{
                type = 2;
                List<DictCacheDO> dictCacheDOList = JD.stream().filter(item -> item.getCode().equals(faceBillBalanceDTO.getOuterCode())).collect(Collectors.toList());
                if(ObjectUtil.isNotNull(dictCacheDOList) && dictCacheDOList.size() > 0){
                    faceBillBalanceDTO.setOuterName(dictCacheDOList.get(0).getName());
                }
                break;
            }
            case "PDD": {
                type = 3;
                List<DictCacheDO> dictCacheDOList = PDD.stream().filter(item -> item.getCode().equals(faceBillBalanceDTO.getOuterCode())).collect(Collectors.toList());
                if(ObjectUtil.isNotNull(dictCacheDOList) && dictCacheDOList.size() > 0){
                    faceBillBalanceDTO.setOuterName(dictCacheDOList.get(0).getName());
                }
                break;
            }
            case "DY": {
                type = 4;
                List<DictCacheDO> dictCacheDOList = DY.stream().filter(item -> item.getCode().equals(faceBillBalanceDTO.getOuterCode())).collect(Collectors.toList());
                if(ObjectUtil.isNotNull(dictCacheDOList) && dictCacheDOList.size() > 0){
                    faceBillBalanceDTO.setOuterName(dictCacheDOList.get(0).getName());
                }
                break;
            }
            case "TB": {
                type = 5;
                List<DictCacheDO> dictCacheDOList = TB.stream().filter(item -> item.getCode().equals(faceBillBalanceDTO.getOuterCode())).collect(Collectors.toList());
                if(ObjectUtil.isNotNull(dictCacheDOList) && dictCacheDOList.size() > 0){
                    faceBillBalanceDTO.setOuterName(dictCacheDOList.get(0).getName());
                }
                break;
            }
            case "KS": {
                type = 6;
                List<DictCacheDO> dictCacheDOList = KS.stream().filter(item -> item.getCode().equals(faceBillBalanceDTO.getOuterCode())).collect(Collectors.toList());
                if(ObjectUtil.isNotNull(dictCacheDOList) && dictCacheDOList.size() > 0){
                    faceBillBalanceDTO.setOuterName(dictCacheDOList.get(0).getName());
                }
                break;
            }
            default: {
                type = 1;
                List<DictCacheDO> dictCacheDOList = TB.stream().filter(item -> item.getCode().equals(faceBillBalanceDTO.getOuterCode())).collect(Collectors.toList());
                if(ObjectUtil.isNotNull(dictCacheDOList) && dictCacheDOList.size() > 0){
                    faceBillBalanceDTO.setOuterName(dictCacheDOList.get(0).getName());
                }
            }
        }
        //拼接
        ElectronicFaceSheetBlanaceDTO electronicFaceSheetBlanaceDTO = new ElectronicFaceSheetBlanaceDTO();
        electronicFaceSheetBlanaceDTO.setType(type);
        electronicFaceSheetBlanaceDTO.setDynamicToken(shop.getAccessToken());
        electronicFaceSheetBlanaceDTO.setAppKey(shop.getAppKey());
        electronicFaceSheetBlanaceDTO.setAppSecret(shop.getAppSecret());
        electronicFaceSheetBlanaceDTO.setCpCode(faceBillBalanceDTO.getOuterCode());
        if(type == 2){
            electronicFaceSheetBlanaceDTO.setMallMerchantCode(shop.getMerchantsCode());
        }
        //先调用获取面单余额的接口 避免异常
        ResultDO resultDO = arpaCloudUtil.getWaybillPrintDataBalance(electronicFaceSheetBlanaceDTO, faceBillBalanceDTO.getGroupCode());
        log.info("从中台获取到的电子面单余额信息为,{}", JSONUtil.toJsonStr(resultDO));
        if (resultDO.getStatus() != 0) {
            JSONObject result = null;
            String msg = StrUtil.EMPTY;
            try {
                result = JSONUtil.parseObj(resultDO.getData());
                msg = (String) result.get("msg");
            } catch (Exception e) {
                //如果解析为JSONObject报异常，在尝试解析为List
                List<Map> resultMapList = JSONUtil.toList(JSONUtil.toJsonStr(resultDO.getData()), Map.class);
                if (IterUtil.isEmpty(resultMapList)){
//                    throw new ServiceException("获取面单余额异常，异常信息为：" + JSONUtil.toJsonStr(resultDO.getData()));
                    log.error("获取面单余额异常，异常信息为：" + JSONUtil.toJsonStr(resultDO.getData()));
                    log.info("获取面单余额异常，异常信息为：" + JSONUtil.toJsonStr(resultDO.getData()));
                } else {
                    msg = (String)resultMapList.get(NumConst.NUM_ZERO).get("msg");
                }
            }
            log.error("{}:{}", "获取面单余额异常：", msg);
            log.info("{}:{}", "获取面单余额异常：", msg);
//            throw new ServiceException("获取面单余额异常：" + msg);
        }else{
            List<ESSElectronicFaceSheetBalanceVO> voList = JSONUtil.toList(JSONUtil.toJsonStr(resultDO.getData()), ESSElectronicFaceSheetBalanceVO.class);
            //赋值
            for (ESSElectronicFaceSheetBalanceVO eSSElectronicFaceSheetBalanceVO:voList){
                BeanUtils.copyProperties(eSSElectronicFaceSheetBalanceVO,faceBillBalanceDTO);
            }
        }
    }
}
